#ifndef __LIB_XBEE_H__
#define __LIB_XBEE_H__

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "Hummingbird.h"
#include <stdarg.h>

#include <sys/mman.h>
#include <signal.h>

#include <termios.h>
#include <sys/signal.h>
#include <sys/select.h>


#define TEMPO
#define DEBUG
//#define MODE_ESPION
#define TRACEROUTE


/**
\enum xbee_error_t
\brief this enumeration define different kinds of errors of libXbee
in general, if a function that return a xbee_error_t type, if funciton was succes, it must \
send XBEE_ERROR_NULL
*/
enum xbee_error_t
{
	XBEE_ERROR_NULL,
	XBEE_DEV_PATH_INVALID,
	XBEE_DEV_ALREADY_OPENED,
	XBEE_DEV_INVALID,
	XBEE_DEV_CANOT_OPEN,
	XBEE_DEV_NOT_INIT,
	XBEE_BUF_MUST_INIT,
	XBEE_READ_TIMEOUT_FIRED,
	XBEE_READ_POLL_ERR,
	XBEE_READ_ERR,
	XBEE_WRITE_TIMEOUT_FIRED,
	XBEE_WRITE_POLL_ERR,
	XBEE_WRITE_ERR
};

extern enum xbee_error_t xbee_error;

static const unsigned char xbee_syncbytes[] =
{
	0x3E,
	0x2A,
	0x3E,
};



enum xbee_packet_descriptor_t
{
	PD_SCIENTIFICCOMMAND 	= 0x17,
	PD_SCIENTIFICSTATUS,	//0x18 surement!
	PD_SCIENTIFICDATA,		//0x19 on l'espere
	PD_SCIENTIFICCONFIG		//0x20 inattendu!!
};

/****	ASTECH HUMMINGBIRD RESEARCHPILOT DATA STRUCTURES 	****/

/**
\struct SCIENTIFIC_COMMANDDATA
\brief this structure define the packet that will be sended for command \
Hummingbird researchpilot model
when you send a packet SCIENTIFIC_COMMANDDATA, Hummingbird researchpilot'll send back to you a packet \
of type \see SCIENTIFIC_STATUSDATA
*/
struct SCIENTIFIC_COMMANDDATA
{
	unsigned char packetdescriptor; //must be PD_SCIENTIFICCOMMAND

	//pitch, roll, thrust, yaw commands. 0..4095 2048=middle
	unsigned short pitch;
	unsigned short roll;
	unsigned short thrust;
	unsigned short yaw;

	//flags
	//Bit 0(0x01): Pitch control through serial interfacae enabled
	//Bit 1(0x02): Roll control through serial interface enabled
	//Bit 2(0x04): Thrust control through serial interface enabled
	//Bit 3(0x08): Yaw control through serial interface enabled
	//Bit 4(0x10): ACC-Mode on/off
	//Bit 5(0x20): Height control - on/off (only with ACC)
	//Bit 6(0x40): overwrite ACC/Height mode control
	//(0=mode selected by RC 1=mode selected by Bit 4 and 5)
	//Bit 7(0x80): Trigger Scientific status packet
	//(triggers a response with the actual scientific state)
	//Bit 8..15: sendrate of the scientific packet in 5Hz
	//(0=off;1=5Hz, 20=100Hz, 200=1kHz, 255=packet is only sent once (polling mode))
	//Scientific packet is send for three seconds max.
	//after the last command_data packet
	unsigned short flags;

} __attribute__((__packed__)); //to avoid padding in send packets

/**
\struct SCIENTIFIC_STATUSDATA
\brief this structure
*/
struct SCIENTIFIC_STATUSDATA
{
	unsigned char packetdescriptor; //must be PD_SCIENTIFICSTATUS

	//flags
	//Bit 0-5 represent the actual status of the ResearchPilot!
	//if the interface is disabled by the remote, all bits are 0!
	//Bit 0(0x01): Pitch control through serial interfacae enabled
	//Bit 1(0x02): Roll control through serial interface enabled
	//Bit 2(0x04): Thrust control through serial interface enabled
	//Bit 3(0x08): Yaw control through serial interface enabled
	//Bit 4(0x10): ACC-Mode on/off
	//Bit 5(0x20): Height control - on/off (only with ACC)
	//Bit 6(0x40): unused
	//Bit 7(0x80): Scientific interface enabled by Remote?
	//1=Interface enabled (control through serial link)
	//0=interface disabled (control through RC)
	//Bit 8..15: sendrate of the scientific packet in 5Hz
	//(0=off;1=5Hz, 20=100Hz, 200=1kHz). Scientific packet
	//is send for three seconds max. after the last command_data packet
	unsigned short flags;

}/*__attribute__((__packed__))*/; //to avoid padding in send packets

/**
\struct SCIENTIFIC_DATA
\brief this structure define the packet that's be returned by hummingbird
\see struct SCIENTIFIC_CONFIG for more details
*/
struct SCIENTIFIC_DATA
{
	unsigned char packetdescriptor; //must be PD_SCIENTIFICDATA

	//length of data field in bytes. Packetlength= length + 4
	unsigned char length;

	//flexible data field. Maximum 32 integers or 64 shorts.
	unsigned char data[128];
};

/**
\struct SCIENTIFIC_CONFIG
\brief this structure define the packet that will be sended for requesting informations from \
Hummingbird researchpilot model
when you send a packet SCIENTIFIC_CONFIG, Hummingbird researchpilot'll send back to you a packet \
of type \see SCIENTIFIC_DATA
*/
struct SCIENTIFIC_CONFIG 
{
	unsigned char packetdescriptor; //must be PD_SCIENTIFICCONFIG

	unsigned char data_select[128];

}__attribute__((__packed__)); //to avoid padding in send packets


union scientific_packet_t {
	struct SCIENTIFIC_COMMANDDATA cmdData;		/* 0x17 */
	struct SCIENTIFIC_DATA data;				/* 0x19 */
	struct SCIENTIFIC_CONFIG config;			/* 0x20 */
	struct SCIENTIFIC_STATUSDATA statusData;	/* 0x18 */
};

/*! this hold the path of xbee device */
extern char *xbee_dev;

/*! structures that hold serial com (over xbee module) configuration
xbee_newconf is the config that will be used to setting up for Hummingbird
xbee_oldconf is original config that we'll set when extting
*/
extern struct termios xbee_newconf, xbee_oldconf;
extern struct timeval xbee_tv;

/*! file descriptor for xbee */
extern int xbee_fd;

/*! fd set for polling */
extern fd_set xbee_fds;


/***	FUNCTIONS SIGNATURES 	*****/
extern unsigned short crc_update(unsigned short ,unsigned char );
extern unsigned short crc16(void *, unsigned short);
extern enum xbee_error_t openXBEEDev(const char *);

/**
\fn xbee_error_t closeXBEEDev()
\brief when this function is fired, it'll close the file descriptor to the xbee device. It also \
puts back old config of serial port (xbee device)
*/
extern enum xbee_error_t closeXBEEDev();

/**
\fn readXBEEDev(void *)
\brief this function'll read from xbee device that previously initialized by calling
\see openXBEEDev(char *)
\param void * is the buffer that data read will bee written on
\param struct timeval * if you want to setting up the timeout period for this operation, NULL if \
none
\return number of bytes read, -1 on error
*/
extern int readXBEEDev(void *,struct timeval*);

/**
\fn writeXBEEDev(void *)
\brief this function is similar to readXBEEDev function, but it allows to write a buffer to \
xbee device
\param xbee_packet_type_t type of packet to write
*/
extern int writeXBEEDev(void *, enum xbee_packet_descriptor_t, unsigned short, struct timeval*);

struct SCIENTIFIC_COMMANDDATA my_commanddata;

/* prototypes */
int add_thrust(short thrust);
int sub_thrust(short thrust);
int add_yaw(short yaw);
int sub_yaw(short yaw);
int add_pitch(short pitch);
int sub_pitch(short pitch);
int add_roll(short roll);
int sub_roll(short roll);
int stop_motors();
int init_pkt_conf();
int traceroute();


#define PITCH_MAX				4095	
#define ROLL_MAX				4095
#define YAW_MAX					4095
#define THRUST_MAX				4095

#define PITCH_MIDDLE				2048	
#define ROLL_MIDDLE				2048
#define YAW_MIDDLE				2048
#define THRUST_MIDDLE				2048
	
#define PITCH_MIN				0	
#define ROLL_MIN				0
#define YAW_MIN					0
#define THRUST_MIN				0

/* flags de commande */
#define PITCH_ENABLED 				0x01 	
#define ROLL_ENABLED				0x02
#define THRUST_ENABLED				0x04
#define YAW_ENABLED				0x08

#define ACC_MODE_ON				0x10
#define HEIGHT_CONTROL_ON			0x20	/* (only with ACC) */
#define MODE_SEL_BIT_4_5			0x40
#define TRIG_SC_STAT_PKT			0x80

/* flags de status */
#define UNUSED 					0x40
#define SC_INTERF_ENED_REMOTE			0x80

#define FIVE_HZ_STEP				0x01
#endif
